// Analytics Service - 学情分析服务

use axum::{
    extract::{Json, Path, State},
    http::StatusCode,
    routing::get,
    Router,
};
use common::ApiResponse;
use serde::{Deserialize, Serialize};
use sqlx::PgPool;
use std::sync::Arc;
use auth::AuthUser;

// ========== 数据模型 ==========

#[derive(Debug, Serialize, Deserialize)]
struct StudentAnalytics {
    student_id: String,
    total_homeworks: i64,
    completed_homeworks: i64,
    average_score: f64,
    weak_points: Vec<WeakPoint>,
    rank_in_class: Option<i32>,
    trend: String,  // improving, declining, stable
}

#[derive(Debug, Serialize, Deserialize)]
struct WeakPoint {
    knowledge_point: String,
    error_count: i64,
    accuracy_rate: f64,
}

#[derive(Debug, Serialize, Deserialize)]
struct ClassAnalytics {
    class_id: String,
    total_students: i64,
    average_score: f64,
    top_performers: Vec<String>,
    needs_help: Vec<String>,
}

// ========== API 请求/响应 ==========

#[derive(Debug, Deserialize)]
struct AnalyticsQuery {
    student_id: Option<String>,
    class_id: Option<String>,
    start_date: Option<String>,
    end_date: Option<String>,
}

// ========== 应用状态 ==========

#[derive(Clone)]
struct AppState {
    db: PgPool,
}

// ========== 处理器 ==========

/// 健康检查
async fn health_check() -> (StatusCode, Json<ApiResponse<String>>) {
    (StatusCode::OK, Json(ApiResponse::ok("OK".to_string())))
}

/// 获取学生学情分析
async fn get_student_analytics(
    _auth_user: AuthUser,
    State(state): State<Arc<AppState>>,
    Path(student_id): Path<String>,
) -> (StatusCode, Json<ApiResponse<StudentAnalytics>>) {
    // 1. 查询学生作业统计
    let stats: Option<(i64, f64)> = sqlx::query_as(
        r#"
        SELECT COUNT(*) as total, COALESCE(AVG(gr.total_score / gr.max_score * 100), 0) as avg_score
        FROM homework_submissions hs
        LEFT JOIN grading_results gr ON hs.id = gr.submission_id
        WHERE hs.student_id = $1
        "#
    )
    .bind(&student_id)
    .fetch_optional(&state.db)
    .await
    .unwrap_or(None);

    let (total, avg_score) = stats.unwrap_or((0, 0.0));

    // 2. 查询薄弱知识点
    let weak_points: Vec<WeakPoint> = sqlx::query_as::<_, (String, i64)>(
        r#"
        SELECT unnest(knowledge_points) as kp, COUNT(*) as cnt
        FROM wrong_answers
        WHERE student_id = $1
        GROUP BY kp
        ORDER BY cnt DESC
        LIMIT 5
        "#
    )
    .bind(&student_id)
    .fetch_all(&state.db)
    .await
    .unwrap_or_default()
    .into_iter()
    .map(|(kp, cnt)| WeakPoint {
        knowledge_point: kp,
        error_count: cnt,
        accuracy_rate: 100.0 - (cnt as f64 / total as f64 * 100.0).min(100.0),
    })
    .collect();

    // 3. 构建分析结果
    let analytics = StudentAnalytics {
        student_id: student_id.clone(),
        total_homeworks: total,
        completed_homeworks: total,  // 简化版
        average_score: avg_score,
        weak_points,
        rank_in_class: None,  // TODO: 计算班级排名
        trend: "stable".to_string(),  // TODO: 分析趋势
    };

    (StatusCode::OK, Json(ApiResponse::ok(analytics)))
}

/// 获取班级学情分析
async fn get_class_analytics(
    _auth_user: AuthUser,
    State(state): State<Arc<AppState>>,
    Path(class_id): Path<String>,
) -> (StatusCode, Json<ApiResponse<ClassAnalytics>>) {
    // 简化版：返回模拟数据
    let total_students: i64 = sqlx::query_scalar(
        "SELECT COUNT(DISTINCT student_id) FROM homework_submissions hs 
         JOIN homeworks h ON hs.homework_id = h.id 
         WHERE h.class_id = $1"
    )
    .bind(&class_id)
    .fetch_one(&state.db)
    .await
    .unwrap_or(0);

    let analytics = ClassAnalytics {
        class_id,
        total_students,
        average_score: 75.0,  // TODO: 实际计算
        top_performers: vec![],  // TODO: 查询
        needs_help: vec![],  // TODO: 查询
    };

    (StatusCode::OK, Json(ApiResponse::ok(analytics)))
}

// ========== 主函数 ==========

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    use common::service::*;
    
    init_tracing();
    dotenvy::dotenv().ok();

    let db = init_db("DATABASE_URL", "postgresql://intelligrade:password@localhost:5432/intelligrade").await?;

    let app = Router::new()
        .route("/health", get(health_check))
        .route("/api/v1/analytics/student/:student_id", get(get_student_analytics))
        .route("/api/v1/analytics/class/:class_id", get(get_class_analytics))
        .with_state(Arc::new(AppState { db }));

    start_service("Analytics service", &env_or("ANALYTICS_SERVICE_PORT", "8084"), app).await
}
